package com.yami.shop.delivery.api.manager;

import cn.hutool.core.collection.CollUtil;
import com.yami.shop.bean.app.dto.OrderSelfStationDto;
import com.yami.shop.bean.app.dto.ShopCartItemDto;
import com.yami.shop.bean.enums.DeliveryType;
import com.yami.shop.bean.enums.ShopCityStatus;
import com.yami.shop.bean.model.UserAddr;
import com.yami.shop.bean.vo.ShopTransFeeVO;
import com.yami.shop.bean.vo.UserDeliveryInfoVO;
import com.yami.shop.delivery.common.model.SameCity;
import com.yami.shop.delivery.common.service.OrderSelfStationService;
import com.yami.shop.delivery.common.service.SameCityService;
import com.yami.shop.delivery.common.service.TransportManagerService;
import com.yami.shop.service.UserAddrService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author 菠萝凤梨
 */
@Component
@AllArgsConstructor
public class DeliveryOrderManager {
    private final OrderSelfStationService orderSelfStationService;
    private final UserAddrService userAddrService;
    private final SameCityService sameCityService;
    private final TransportManagerService transportManagerService;

    /**
     * 计算运费，并计算获取配送信息
     * @param userId 用户id
     * @param addrId 地址ID，0为默认地址
     * @param dvyType 配送类型 1:快递 2:自提 3：无需快递 4:同城配送
     * @param shopCartItems 购物项
     * @return
     */
    public UserDeliveryInfoVO calculateAndGetDeliverInfo(String userId, Long addrId,
                                                         Integer dvyType, List<ShopCartItemDto> shopCartItems) {
        UserDeliveryInfoVO userDeliveryInfo = new UserDeliveryInfoVO();
        userDeliveryInfo.setTotalTransFee(0.0);

        //如果是自提，查出用户常用的自提信息
        if (Objects.equals(dvyType, DeliveryType.STATION.getValue())) {
            List<OrderSelfStationDto> userStationList = orderSelfStationService.getUserStation(userId);
            userDeliveryInfo.setOrderSelfStation(userStationList);
            userDeliveryInfo.setTotalFreeTransFee(0.0);
            return userDeliveryInfo;
        }

        //订单的地址信息
        UserAddr userAddr = userAddrService.getUserAddrByUserId(addrId, userId);
        if (Objects.isNull(userAddr)) {
            userDeliveryInfo.setTotalFreeTransFee(0.0);
            userDeliveryInfo.setShopCityStatus(ShopCityStatus.OUT_OF_RANGE.value());
            return userDeliveryInfo;
        }

        userDeliveryInfo.setUserAddr(userAddr);

        double transFee = 0.0;
        if (Objects.equals(dvyType, DeliveryType.SAME_CITY.getValue())) {
            // 同城配送
            transFee = sameCityService.calculateTransFee(shopCartItems, userAddr);
            Long shopId = shopCartItems.get(0).getShopId();
            Map<Long, ShopTransFeeVO> shopIdWithShopTransFee = new HashMap<>(16);
            ShopTransFeeVO shopTransFeeVO = new ShopTransFeeVO();
            shopTransFeeVO.setTransFee(Math.max(transFee, 0.0));
            shopTransFeeVO.setFreeTransFee(0.0);
            shopIdWithShopTransFee.put(shopId, shopTransFeeVO);
            userDeliveryInfo.setShopIdWithShopTransFee(shopIdWithShopTransFee);
            SameCity sameCity = sameCityService.getSameCityByShopId(shopId);
            if (Objects.nonNull(sameCity)) {
                // 同城配送起送费
                userDeliveryInfo.setStartDeliveryFee(sameCity.getStartingFee());
            }
        }
        if (Objects.equals(dvyType, DeliveryType.EXPRESS.getValue())) {
            // 快递
            transFee = transportManagerService.calculateTransFee(shopCartItems, userAddr, userDeliveryInfo);
        }
        double actualTransFee = Math.max(transFee, 0.0);
        userDeliveryInfo.setTotalTransFee(actualTransFee);
        userDeliveryInfo.setShopCityStatus(transFee >= 0.0 ? ShopCityStatus.USABLE.value() : (int)transFee);
        List<Long> shopIds = shopCartItems.stream().distinct().map(ShopCartItemDto::getShopId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(shopIds)) {
            // 多店铺同城配送状态判断
            for (Long shopId : shopIds) {
                SameCity sameCity = sameCityService.getSameCityByShopId(shopId);
                if (Objects.nonNull(sameCity) && Objects.equals(sameCity.getStatus(), 0)) {
                    userDeliveryInfo.setShopCityStatus(ShopCityStatus.NO_CONFIG.value());
                    break;
                }
            }
        }
        return userDeliveryInfo;
    }
}
